package com.heima.search.service.impl;

import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.search.dtos.UserSearchDto;
import com.heima.search.service.ApUserSearchService;
import com.heima.search.service.ArticleSearchService;
import com.heima.search.util.ThreadLocalUtil;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

@Service
@Slf4j
public class ArticleSearchServiceImpl implements ArticleSearchService {
    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private ApUserSearchService apUserSearchService;

    @Override
    public ResponseResult search(UserSearchDto dto) {
        apUserSearchService.insert(dto.getSearchWords(), ThreadLocalUtil.get());

        try {
            SearchRequest searchRequest= new SearchRequest("app_info_article");

            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
            //构建bool
            BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

            //设置在标题和内容中去寻找
            QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery(dto.getSearchWords());
            queryStringQueryBuilder.field("title").field("content").defaultOperator(Operator.OR);

            boolQueryBuilder.must(queryStringQueryBuilder);
            //设置最小时间
            RangeQueryBuilder publishTime = QueryBuilders.rangeQuery("publishTime").lte(dto.getMinBehotTime());
            boolQueryBuilder.must(publishTime);

            //将查询请求拼装
            searchSourceBuilder.query(boolQueryBuilder);
            //进行分页
            searchSourceBuilder.size(dto.getPageSize());
            searchSourceBuilder.from(dto.getFromIndex());
            //按照提交时间倒叙
            searchSourceBuilder.sort("publishTime", SortOrder.DESC);
            //拼接高亮字符
            HighlightBuilder highlightBuilder = new HighlightBuilder();
            highlightBuilder.field("title");
            highlightBuilder.preTags("<font style='color: red; font-size: inherit;'>");
            highlightBuilder.postTags("</font>");
            searchSourceBuilder.highlighter(highlightBuilder);

            searchRequest.source(searchSourceBuilder);


            SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            ArrayList arrayList = new ArrayList();
            SearchHit[] hits = search.getHits().getHits();
            for (SearchHit hit : hits) {
                Map<String, Object> sourceAsMap = hit.getSourceAsMap();
                if (hit.getHighlightFields() != null && !hit.getHighlightFields().isEmpty()){
                    sourceAsMap.put("h_title",hit.getHighlightFields().get("title").getFragments()[0].string());
                }
                arrayList.add(sourceAsMap);
            }


            return ResponseResult.okResult(arrayList);
        } catch (IOException e) {
            e.printStackTrace();
            return  ResponseResult.errorResult(403,"查询出现异常");
        }
    }
}
